Skip to content

feat(dock): integrate optional event logging support#1569

Merged
deepin-bot[bot] merged 1 commit intolinuxdeepin:masterfrom
Ivy233:feat/event-logger-integration
Apr 30, 2026
Merged

feat(dock): integrate optional event logging support#1569
deepin-bot[bot] merged 1 commit intolinuxdeepin:masterfrom
Ivy233:feat/event-logger-integration

Conversation

@Ivy233
Copy link
Copy Markdown
Contributor

@Ivy233 Ivy233 commented Apr 26, 2026

Add conditional event logging support for dock-related modules and wire the required build detection and package dependency. The implementation keeps the logging integration optional when the event logger headers are unavailable.

feat(dock): 集成可选事件日志支持

为 dock 相关模块添加条件事件日志支持,并接入所需的构建检测与包依赖。该实现会在缺少事件日志头文件时保持日志集成可选。

PMS: TASK-388657

Summary by Sourcery

Integrate optional event logging across dock components while keeping functionality unchanged when the dde-api event logger is unavailable.

New Features:

  • Add event logging for tray plugin list visibility changes in the dock DBus proxy.
  • Log dock position and alignment configuration changes via the event logger.
  • Record multitask view launches from the dock, including KWin version metadata.
  • Track task manager merge-app-model configuration changes through the event logger.

Enhancements:

  • Update dock and taskmanager source headers with extended copyright years.
  • Introduce helper functions for computing visible tray plugin lists used by logging.

Build:

  • Add CMake detection for dde-api eventlogger headers and define a HAVE_DDE_API_EVENTLOGGER compile flag.
  • Wire the HAVE_DDE_API_EVENTLOGGER definition into dock, taskmanager, and multitaskview targets so logging is compiled conditionally.

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented Apr 26, 2026

Reviewer's Guide

Adds optional dde-api-based event logging to dock-related components (dock DBus proxy, dock settings, multitask view, and task manager settings), guarded by a new CMake-detected HAVE_DDE_API_EVENTLOGGER macro so that logging is enabled only when the eventlogger.hpp header is available.

Sequence diagram for tray plugin visibility change logging via DockDBusProxy

sequenceDiagram
    actor User
    participant DockUI
    participant DockDBusProxy
    participant DockSettings
    participant EventLogger as DDE_EventLogger.EventLogger

    User->>DockUI: Toggle tray plugin visibility
    DockUI->>DockDBusProxy: setItemOnDock(settingKey, itemKey, visible)

    alt trayApplet not ready
        DockDBusProxy->>DockSettings: setPluginsVisible(updatedPluginsVisible)
        DockDBusProxy->>DockDBusProxy: logTrayPluginListChange(itemKey, visible)
    else trayApplet ready
        DockDBusProxy->>DockDBusProxy: pluginVisibleChanged(itemKey, visible)
        DockDBusProxy->>DockDBusProxy: logTrayPluginListChange(itemKey, visible)
    end

    DockDBusProxy->>DockDBusProxy: plugins() %% collect DockItemInfos
    DockDBusProxy->>DockDBusProxy: visiblePluginCount(itemInfos)
    alt visible plugin count changed
        DockDBusProxy->>DockDBusProxy: visiblePluginList(itemInfos)
        DockDBusProxy->>EventLogger: writeEventLog(EventLoggerData(EVENT_LOGGER_TRAY_PLUGIN_LIST, taskmanager_config, payload))
        DockDBusProxy->>DockDBusProxy: update m_visiblePluginCount
    else unchanged
        DockDBusProxy-->>DockDBusProxy: return without logging
    end
Loading

Updated class diagram for dock event logging integration

classDiagram
    class DockDBusProxy {
        +DockDBusProxy(DockPanel* parent)
        +DockItemInfos plugins()
        +void setItemOnDock(QString settingKey, QString itemKey, bool visible)
        +void updateDockPluginsVisible(QVariantMap pluginsVisible)
        #DS_NAMESPACE::DAppletProxy* m_oldDockApplet
        #DS_NAMESPACE::DAppletProxy* m_trayApplet
        #QTimer m_trayPluginListLogTimer
        #int m_visiblePluginCount
        +void logTrayPluginList()
        +void logTrayPluginListChange(QString changedItemKey, bool visible)
    }

    class DockSettings {
        +DockSettings(QObject* parent)
        +void init()
        +Position position()
        +void setPosition(Position position)
        +ItemAlignment itemAlignment()
        +void setItemAlignment(ItemAlignment alignment)
        -void addWriteJob(QString job)
        -Position m_dockPosition
        -ItemAlignment m_alignment
        -QScopedPointer~DConfig~ m_dockConfig
    }

    class MultiTaskView {
        +MultiTaskView(QObject* parent)
        +bool init()
        +void openWorkspace()
        -QString m_iconName
        -QObject* m_multitaskview
        -bool m_kWinEffect
    }

    class TaskManagerSettings {
        +TaskManagerSettings(QObject* parent)
        +bool isAllowedForceQuit()
        +bool mergeAppModel()
        +void setMergeAppModel(bool enable)
        +QStringList dockedElements()
        +void addDockedElement(QString element)
        +void removeDockedElement(QString element)
        +void logMergeAppModel(bool mergeAppModelOn)
        -void migrateFromDockedItems()
        -void saveDockedElements()
        -QScopedPointer~DConfig~ m_taskManagerDconfig
        -bool m_windowSplit
        -QStringList m_dockedElements
    }

    class EventLogger {
        +static EventLogger& instance()
        +void init(QString appId, bool sync)
        +void writeEventLog(EventLoggerData data)
    }

    class EventLoggerData {
        +EventLoggerData(qint64 eventId, QString category, QJsonObject payload)
        +qint64 eventId
        +QString category
        +QJsonObject payload
    }

    class DockPanel {
        +void ReloadPlugins()
    }

    class DConfig {
        +QVariant value(QString key)
        +void setValue(QString key, QVariant value)
        +void valueChanged(QString key)
    }

    DockDBusProxy --> DockPanel : parent
    DockDBusProxy --> EventLogger : writeEventLog
    DockSettings --> EventLogger : writeEventLog
    MultiTaskView --> EventLogger : writeEventLog
    TaskManagerSettings --> EventLogger : writeEventLog

    EventLoggerData --> EventLogger : used_by

    DockSettings --> DConfig : m_dockConfig
    TaskManagerSettings --> DConfig : m_taskManagerDconfig
Loading

File-Level Changes

Change Details Files
Integrate tray plugin list event logging into the dock DBus proxy, including initial delayed logging and per-plugin visibility changes, guarded by HAVE_DDE_API_EVENTLOGGER.
  • Include dde-api/eventlogger.hpp and define an EVENT_LOGGER_TRAY_PLUGIN_LIST event ID when event logging is available
  • Add helper functions to derive the visible tray plugin list and visible count from DockItemInfos
  • Initialize the global EventLogger instance in DockDBusProxy, configure a single-shot QTimer to delay initial tray plugin list logging, and hook it up after the tray applet is ready
  • Implement logTrayPluginList and logTrayPluginListChange methods to write tray plugin list changes to the event logger only when the visible count actually changes
  • Invoke event logging helpers from setItemOnDock when plugin visibility changes and store logging-related state (timer and visible count) in the class
panels/dock/dockdbusproxy.cpp
panels/dock/dockdbusproxy.h
Add event logging for dock configuration (position and alignment) inside DockSettings, including startup and runtime changes.
  • Include dde-api/eventlogger.hpp and define an EVENT_LOGGER_DOCK_CONFIG event ID in docksettings.cpp under HAVE_DDE_API_EVENTLOGGER
  • Initialize the EventLogger instance in the DockSettings constructor and log the initial dock position and alignment at startup
  • On position changes, emit an event log with the new shell_pos and keep existing config persistence, with a fallback qCInfo message when logging is unavailable
  • On item alignment changes, emit an event log with the new shell_dock_mode similarly guarded with compile-time checks
  • Update the SPDX copyright years
panels/dock/docksettings.cpp
Log multitask view invocations from the dock, including kwin version, when the feature is available.
  • Conditionally include QProcess and dde-api/eventlogger.hpp and define an EVENT_LOGGER_KWIN_MULTITASK_VIEW event ID and launch type constant
  • Add a helper to query the installed kwin-x11 package version via dpkg-query with a timeout and cache the result
  • Add a logMultiTaskViewEvent helper that writes a kwin_multitask_view event with launch_type and kwin_version
  • Initialize the EventLogger in MultiTaskView’s constructor and call logMultiTaskViewEvent from openWorkspace before toggling the effect
panels/dock/multitaskview/multitaskview.cpp
Emit event logs when the task manager’s merge-app-model setting changes, and ensure logging is initialized for task manager settings.
  • Include dde-api/eventlogger.hpp and define an EVENT_LOGGER_MERGE_APP_MODEL event ID in taskmanagersettings.cpp, with a corresponding logMergeAppModel method
  • Initialize the EventLogger instance in the TaskManagerSettings constructor
  • On TASKMANAGER_WINDOWSPLIT_KEY changes, call logMergeAppModel with the inverted windowSplit value (merge on = !windowSplit)
  • Emit an initial merge_app_model_on event during construction using the current windowSplit value
  • Guard the logging helper with HAVE_DDE_API_EVENTLOGGER in the header
panels/dock/taskmanager/taskmanagersettings.cpp
panels/dock/taskmanager/taskmanagersettings.h
Wire up build-time detection and conditional compilation flags for dde-api event logging.
  • Add a CMake check in the top-level CMakeLists.txt to find dde-api/eventlogger.hpp, set HAVE_DDE_API_EVENTLOGGER, and print a status message when found or missing
  • Propagate HAVE_DDE_API_EVENTLOGGER as a compile definition to dockpanel, dock-taskmanager, and dock-multitaskview targets so that logging code is compiled only when available
  • Update SPDX headers in affected CMakeLists.txt files to reflect the 2023–2026 date range
CMakeLists.txt
panels/dock/CMakeLists.txt
panels/dock/taskmanager/CMakeLists.txt
panels/dock/multitaskview/CMakeLists.txt

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 4 issues, and left some high level feedback:

  • EventLogger::instance().init("org.deepin.dde.shell", false) is called in multiple classes (DockDBusProxy, DockSettings, MultiTaskView, TaskManagerSettings); consider centralizing this initialization or adding a shared helper to avoid repeated init calls and make future changes to the logger setup easier to manage.
  • DockDBusProxy::logTrayPluginList and logTrayPluginListChange both recompute visible counts, plugin lists and then write essentially the same event; factoring this into a shared helper (e.g., logTrayPluginList(const DockItemInfos &)) would reduce duplication and the risk of inconsistent behavior between the two paths.
  • Several new logging calls use qDebug()/qCInfo for event logger messages that may fire on user interactions (e.g., tray plugin changes, dock position/mode changes, merge_app_model toggles); consider routing these through appropriate logging categories and levels or reducing their verbosity to avoid noisy logs in normal operation.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- EventLogger::instance().init("org.deepin.dde.shell", false) is called in multiple classes (DockDBusProxy, DockSettings, MultiTaskView, TaskManagerSettings); consider centralizing this initialization or adding a shared helper to avoid repeated init calls and make future changes to the logger setup easier to manage.
- DockDBusProxy::logTrayPluginList and logTrayPluginListChange both recompute visible counts, plugin lists and then write essentially the same event; factoring this into a shared helper (e.g., logTrayPluginList(const DockItemInfos &)) would reduce duplication and the risk of inconsistent behavior between the two paths.
- Several new logging calls use qDebug()/qCInfo for event logger messages that may fire on user interactions (e.g., tray plugin changes, dock position/mode changes, merge_app_model toggles); consider routing these through appropriate logging categories and levels or reducing their verbosity to avoid noisy logs in normal operation.

## Individual Comments

### Comment 1
<location path="panels/dock/multitaskview/multitaskview.cpp" line_range="31-36" />
<code_context>
+constexpr qint64 EVENT_LOGGER_KWIN_MULTITASK_VIEW = 1000300000;
+constexpr int EventLaunchTypeDockIcon = 2;
+
+QString kwinVersion()
+{
+    static const QString version = [] {
+        QProcess process;
+        process.start(QStringLiteral("dpkg-query"), { QStringLiteral("-W"), QStringLiteral("-f=${Version}"), QStringLiteral("kwin-x11") });
+        if (!process.waitForFinished(1000) || process.exitStatus() != QProcess::NormalExit || process.exitCode() != 0) {
+            return QString();
+        }
</code_context>
<issue_to_address>
**issue (performance):** Blocking dpkg-query call on the UI path can freeze the dock for up to 1s on first use.

This runs in the GUI thread on the first call (via `openWorkspace()``logMultiTaskViewEvent()`), so the synchronous `dpkg-query` + `waitForFinished(1000)` can stall the interface. Please move this work off the UI thread (e.g., background task or lazy, non-blocking init with caching), and/or reduce the timeout and handle failures without blocking.
</issue_to_address>

### Comment 2
<location path="panels/dock/docksettings.cpp" line_range="270" />
<code_context>
+void DockSettings::setPosition(const Position& position)
</code_context>
<issue_to_address>
**question (bug_risk):** Dock config events after startup only include one of shell_pos or shell_dock_mode, which may surprise downstream consumers.

On startup, `dock_config` includes both `shell_pos` and `shell_dock_mode`, but subsequent updates (`setPosition` / `setItemAlignment`) emit only the changed field. If consumers treat each event as a full snapshot, this will produce partial records. Either always emit both fields (using current in-memory state) on each update, or clearly define these events as incremental and document/encode them as such.
</issue_to_address>

### Comment 3
<location path="panels/dock/dockdbusproxy.cpp" line_range="14" />
<code_context>
 #include <QObject>
+#include <QJsonObject>
+
+#ifdef HAVE_DDE_API_EVENTLOGGER
+#include <dde-api/eventlogger.hpp>
+#endif
</code_context>
<issue_to_address>
**issue (complexity):** Consider refactoring the new event-logging code by extracting shared aggregation and logging helpers and simplifying the timer wiring to avoid duplication and clarify control flow.

You can reduce duplication and simplify flow without changing behavior by extracting shared logic and slightly restructuring the timer wiring.

### 1. Deduplicate `logTrayPluginList` / `logTrayPluginListChange`

Both functions compute `itemInfos`, then do the same “count → compare → update → list → log” sequence. Extract that into a single helper and reuse it:

```cpp
#ifdef HAVE_DDE_API_EVENTLOGGER
bool DockDBusProxy::updateAndLogTrayPluginList(const DockItemInfos &itemInfos)
{
    const int count = visiblePluginCount(itemInfos);
    if (count == m_visiblePluginCount)
        return false;

    m_visiblePluginCount = count;
    const QString trayPluginList = visiblePluginList(itemInfos);

    DDE_EventLogger::EventLogger::instance().writeEventLog(
        DDE_EventLogger::EventLoggerData(EVENT_LOGGER_TRAY_PLUGIN_LIST,
                                         QStringLiteral("taskmanager_config"),
                                         { { QStringLiteral("tray_plugin_list"), trayPluginList } }));
    qDebug() << "EventLogger: tray_plugin_list:" << trayPluginList;
    return true;
}

void DockDBusProxy::logTrayPluginList()
{
    updateAndLogTrayPluginList(plugins());
}

void DockDBusProxy::logTrayPluginListChange(const QString &changedItemKey, bool visible)
{
    DockItemInfos itemInfos = plugins();
    for (DockItemInfo &itemInfo : itemInfos) {
        if (itemInfo.itemKey == changedItemKey) {
            itemInfo.visible = visible;
            break;
        }
    }
    updateAndLogTrayPluginList(itemInfos);
}
#endif
```

This keeps the event format and debug output in one place and makes future changes less error‑prone.

### 2. Unify aggregation over `DockItemInfos`

`visiblePluginList` and `visiblePluginCount` are very similar traversals. You can keep both public helpers but internally share a single aggregation, avoiding drift if the filter logic changes:

```cpp
#ifdef HAVE_DDE_API_EVENTLOGGER
struct VisiblePluginStats {
    int count = 0;
    QString list;
};

VisiblePluginStats visiblePluginStats(const DockItemInfos &itemInfos)
{
    QStringList pluginNames;
    int count = 0;
    for (const DockItemInfo &itemInfo : itemInfos) {
        if (itemInfo.visible) {
            ++count;
            if (!itemInfo.name.isEmpty())
                pluginNames.append(itemInfo.name);
        }
    }
    pluginNames.removeDuplicates();
    return { count, pluginNames.join(QStringLiteral(",")) };
}

QString visiblePluginList(const DockItemInfos &itemInfos)
{
    return visiblePluginStats(itemInfos).list;
}

int visiblePluginCount(const DockItemInfos &itemInfos)
{
    return visiblePluginStats(itemInfos).count;
}
#endif
```

This keeps all filter logic in one spot while preserving your existing API.

### 3. Simplify timer + signal wiring

Right now the `QTimer` timeout connects `pluginsChanged` to `logTrayPluginList` inside the timeout lambda. You can make the lifecycle more obvious by always wiring `pluginsChanged` to restart the one‑shot timer, and let the timer be the only place that calls `logTrayPluginList()`:

```cpp
#ifdef HAVE_DDE_API_EVENTLOGGER
DockDBusProxy::DockDBusProxy(DockPanel* parent)
    : QObject(parent)
    , m_oldDockApplet(nullptr)
    , m_trayApplet(nullptr)
{
    // ...
    DDE_EventLogger::EventLogger::instance().init("org.deepin.dde.shell", false);
    m_trayPluginListLogTimer.setSingleShot(true);
    m_trayPluginListLogTimer.setInterval(1000);
    connect(&m_trayPluginListLogTimer, &QTimer::timeout,
            this, &DockDBusProxy::logTrayPluginList);
    // ...
    QTimer *timer = new QTimer;
    timer->setInterval(1000);
    connect(timer, &QTimer::timeout, this, [=] {
        if (getOtherApplet()) {
            timer->stop();
            timer->deleteLater();
            connect(m_trayApplet, SIGNAL(pluginsChanged()),
                    this, SIGNAL(pluginsChanged()));
            connect(this, &DockDBusProxy::pluginsChanged, this, [this] {
                m_trayPluginListLogTimer.start();
            }, Qt::UniqueConnection);
            m_trayPluginListLogTimer.start(); // initial delayed log
        }
    });
    timer->start();
}
#endif
```

This keeps the “debounce and delay logging by 1s” behavior but makes the control flow easier to follow: `pluginsChanged` → restart timer → timer timeout → `logTrayPluginList()`.
</issue_to_address>

### Comment 4
<location path="panels/dock/docksettings.cpp" line_range="12" />
<code_context>
 #include <QObject>
+#include <QJsonObject>
+
+#ifdef HAVE_DDE_API_EVENTLOGGER
+#include <dde-api/eventlogger.hpp>
+#endif
</code_context>
<issue_to_address>
**issue (complexity):** Consider extracting the event-logging logic into small helper methods to centralize the schema and avoid repeating conditional blocks across the class.

You can reduce duplication and centralize the event‑logging schema by introducing small helpers and reusing them instead of inlining `#ifdef` blocks in multiple places.

### 1. Centralize dock config logging

Add a private helper in `DockSettings`:

```cpp
// docksettings.h
class DockSettings : public QObject {
    Q_OBJECT
    // ...
private:
    void logDockConfig(std::optional<Position> pos,
                       std::optional<ItemAlignment> align,
                       const QString &reason) const;
};
```

```cpp
// docksettings.cpp
void DockSettings::logDockConfig(std::optional<Position> pos,
                                 std::optional<ItemAlignment> align,
                                 const QString &reason) const
{
#ifdef HAVE_DDE_API_EVENTLOGGER
    QVariantMap payload;
    if (pos)
        payload.insert("shell_pos", position2String(*pos));
    if (align)
        payload.insert("shell_dock_mode", itemAlignment2String(*align));

    DDE_EventLogger::EventLogger::instance().writeEventLog(
        DDE_EventLogger::EventLoggerData(EVENT_LOGGER_DOCK_CONFIG, "dock_config", payload));
    qCInfo(dockSettingsLog) << "EventLogger: dock config" << reason << payload;
#else
    Q_UNUSED(pos);
    Q_UNUSED(align);
    qCInfo(dockSettingsLog) << "EventLogger not available:" << reason;
#endif
}
```

Then simplify the call sites:

```cpp
void DockSettings::init()
{
    if (m_dockConfig && m_dockConfig->isValid()) {
        // ... load config as before ...

        logDockConfig(m_dockPosition, m_alignment, QStringLiteral("on startup"));

        // connect(m_dockConfig, ...) unchanged
    }
}

void DockSettings::setPosition(const Position& position)
{
    if (position == m_dockPosition) return;

    m_dockPosition = position;
    Q_EMIT positionChanged(m_dockPosition);
    addWriteJob(positionJob);

    logDockConfig(position, std::nullopt, QStringLiteral("position changed"));
}

void DockSettings::setItemAlignment(const ItemAlignment& alignment)
{
    if (alignment == m_alignment) return;

    m_alignment = alignment;
    Q_EMIT itemAlignmentChanged(m_alignment);
    addWriteJob(itemAlignmentJob);

    logDockConfig(std::nullopt, alignment, QStringLiteral("itemAlignment changed"));
}
```

This keeps the event ID, event name, and key names in one place and removes repeated `#ifdef` clutter from the setters.

### 2. Isolate EventLogger initialization

Similarly, hide the constructor `#ifdef` behind a small helper:

```cpp
// docksettings.h
private:
    void initEventLogger();
```

```cpp
// docksettings.cpp
void DockSettings::initEventLogger()
{
#ifdef HAVE_DDE_API_EVENTLOGGER
    DDE_EventLogger::EventLogger::instance().init("org.deepin.dde.shell", false);
    qCInfo(dockSettingsLog) << "EventLogger initialized";
#else
    qCInfo(dockSettingsLog) << "EventLogger not available (dde-api eventlogger.hpp not found)";
#endif
}

DockSettings::DockSettings(QObject *parent)
    : QObject(parent)
    , m_writeTimer(new QTimer(this))
    // ...
{
    m_writeTimer->setSingleShot(true);
    m_writeTimer->setInterval(1000);

    initEventLogger();
    init();
}
```

This preserves all existing functionality while making the primary behavior of `DockSettings` (state, signals, persistence) easier to read and keeping logging logic maintainable.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread panels/dock/multitaskview/multitaskview.cpp Outdated
Comment thread panels/dock/docksettings.cpp Outdated
Comment thread panels/dock/dockdbusproxy.cpp
Comment thread panels/dock/docksettings.cpp
@Ivy233 Ivy233 force-pushed the feat/event-logger-integration branch 2 times, most recently from ef4e814 to 729c624 Compare April 27, 2026 05:00
@Ivy233 Ivy233 force-pushed the feat/event-logger-integration branch from 729c624 to 3a58b83 Compare April 28, 2026 07:19
Comment thread panels/dock/multitaskview/multitaskview.cpp Outdated
Comment thread panels/dock/multitaskview/multitaskview.cpp Outdated
Comment thread panels/dock/dockdbusproxy.cpp Outdated
@Ivy233 Ivy233 force-pushed the feat/event-logger-integration branch 2 times, most recently from db6b171 to 06e2df5 Compare April 29, 2026 06:34
@deepin-bot
Copy link
Copy Markdown

deepin-bot Bot commented Apr 29, 2026

TAG Bot

New tag: 2.0.39
DISTRIBUTION: unstable
Suggest: synchronizing this PR through rebase #1580

@Ivy233 Ivy233 force-pushed the feat/event-logger-integration branch from 06e2df5 to 9eb0deb Compare April 29, 2026 10:11
@Ivy233 Ivy233 requested a review from 18202781743 April 29, 2026 10:12
@Ivy233 Ivy233 force-pushed the feat/event-logger-integration branch from 9eb0deb to aeb7034 Compare April 29, 2026 11:20
Comment thread panels/dock/dockdbusproxy.cpp
Comment thread panels/dock/dockdbusproxy.cpp Outdated
@Ivy233 Ivy233 force-pushed the feat/event-logger-integration branch from aeb7034 to f1bfb5b Compare April 29, 2026 13:09
@deepin-ci-robot
Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: 18202781743, Ivy233

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@Ivy233 Ivy233 force-pushed the feat/event-logger-integration branch from f1bfb5b to 9bf7407 Compare April 29, 2026 13:24
集成事件日志记录并使用 cmake find_package 管理

- Migrate from find_path to find_package(DDEAPI)
- Add debounce timer for initial plugin state logging
- Remove manual init in DockPanel::load() (now auto-initialized)
- Link DDEAPI::EventLogger to dockpanel, multitaskview, taskmanager

PMS: TASK-388657
@Ivy233 Ivy233 force-pushed the feat/event-logger-integration branch from 9bf7407 to ee8a493 Compare April 30, 2026 05:02
@deepin-ci-robot
Copy link
Copy Markdown

deepin pr auto review

Git Diff 代码审查报告

总体评价

该代码 diff 主要为 Dock 面板添加了事件日志记录功能,通过集成 DDEAPI 的 EventLogger 组件来记录各种用户交互和配置变更。整体实现较为完整,但存在一些可以改进的地方。

详细审查意见

1. 语法逻辑

问题1:在 dockdbusproxy.cpp 中,logCurrentVisiblePluginList 函数的逻辑可以简化

void DockDBusProxy::logCurrentVisiblePluginList(const QString &changedItemKey, bool changedVisible)
{
    QStringList visibleItemKeys;
    for (const auto &info : plugins()) {
        if (info.itemKey == changedItemKey) {
            if (changedVisible)
                visibleItemKeys.append(info.itemKey);
        } else if (info.visible) {
            visibleItemKeys.append(info.itemKey);
        }
    }
    // ...
}

建议:可以简化为:

void DockDBusProxy::logCurrentVisiblePluginList(const QString &changedItemKey, bool changedVisible)
{
    QStringList visibleItemKeys;
    for (const auto &info : plugins()) {
        bool isVisible = (info.itemKey == changedItemKey) ? changedVisible : info.visible;
        if (isVisible) {
            visibleItemKeys.append(info.itemKey);
        }
    }
    // ...
}

问题2:在 dockdbusproxy.cpp 中,logInitialPluginState 函数被延迟3秒调用

QTimer::singleShot(3000, this, [this]() {
    logInitialPluginState();
});

建议:3秒的延迟是硬编码的,建议将其定义为常量,并添加注释说明为什么需要延迟。

2. 代码质量

问题1:缺少错误处理
multitaskview.cpp 中,queryKwinVersion 函数没有处理进程启动失败的情况:

void MultiTaskView::queryKwinVersion()
{
    auto *process = new QProcess(this);
    process->start(QStringLiteral("dpkg-query"), { QStringLiteral("-W"), QStringLiteral("-f=${Version}"), QStringLiteral("kwin-x11") });
    connect(process, &QProcess::finished, this, [this, process](int exitCode, QProcess::ExitStatus status) {
        if (status == QProcess::NormalExit && exitCode == 0) {
            m_kwinVersion = QString::fromLocal8Bit(process->readAllStandardOutput()).trimmed();
        }
        process->deleteLater();
    });
}

建议:添加错误处理和日志记录:

void MultiTaskView::queryKwinVersion()
{
    auto *process = new QProcess(this);
    process->start(QStringLiteral("dpkg-query"), { QStringLiteral("-W"), QStringLiteral("-f=${Version}"), QStringLiteral("kwin-x11") });
    
    if (!process->waitForStarted()) {
        qWarning() << "Failed to start dpkg-query process";
        process->deleteLater();
        return;
    }
    
    connect(process, &QProcess::finished, this, [this, process](int exitCode, QProcess::ExitStatus status) {
        if (status == QProcess::NormalExit && exitCode == 0) {
            m_kwinVersion = QString::fromLocal8Bit(process->readAllStandardOutput()).trimmed();
            qDebug() << "Retrieved KWin version:" << m_kwinVersion;
        } else {
            qWarning() << "Failed to query KWin version, exit code:" << exitCode;
        }
        process->deleteLater();
    });
}

问题2:缺少对 EventLogger 初始化失败的检查
建议:在使用 EventLogger 之前,应该检查它是否正确初始化,例如:

#ifdef HAVE_DDE_API_EVENTLOGGER
    if (DDE_EventLogger::EventLogger::instance().isInitialized()) {
        DDE_EventLogger::EventLogger::instance().writeEventLog(...);
    }
#endif

3. 代码性能

问题1:在 logCurrentVisiblePluginListlogInitialPluginState 中,每次调用 plugins() 都会获取完整的插件列表
建议:如果 plugins() 函数有性能开销,考虑缓存结果或优化调用方式。

问题2:在 queryKwinVersion 中使用 dpkg-query 命令查询版本
建议:这种通过外部进程查询版本的方式可能有性能开销,考虑是否有更直接的方式获取版本信息,或者在应用启动时只查询一次并缓存结果。

4. 代码安全

问题1:在 logInitialPluginStatelogCurrentVisiblePluginList 中,直接将插件列表拼接成字符串

{QStringLiteral("tray_plugin_list"), visibleItemKeys.join(QStringLiteral(","))}

建议:如果插件名称可能包含特殊字符,应该考虑进行适当的转义或使用更安全的数据格式(如JSON数组)。

问题2:在 queryKwinVersion 中使用外部命令

process->start(QStringLiteral("dpkg-query"), { QStringLiteral("-W"), QStringLiteral("-f=${Version}"), QStringLiteral("kwin-x11") });

建议:确保命令参数是安全的,避免命令注入风险。当前实现使用了参数列表,这是安全的做法,但应该保持这种方式。

5. 其他建议

  1. 事件ID管理:所有事件ID都是硬编码的10位数字(如 EVENT_LOGGER_TRAY_PLUGIN_LIST = 1000610007),建议集中管理这些ID,并添加注释说明每个ID的用途。

  2. 日志级别:当前使用 qCInfoqDebug 记录日志,考虑是否需要使用更合适的日志级别。

  3. 代码注释:添加更多注释说明为什么需要记录这些事件,以及这些事件将如何被使用。

  4. 测试覆盖:确保添加了足够的单元测试来验证日志记录功能。

  5. 版本控制:在 dockpanel.cppdocksettings.cpp 中更新了版权年份到2026年,确保这是有意为之,而不是错误。

总结

该代码 diff 实现了事件日志记录功能,整体结构合理,但可以在错误处理、性能优化和代码安全性方面进行改进。建议在合并前考虑上述意见,以提高代码质量和健壮性。

@Ivy233
Copy link
Copy Markdown
Contributor Author

Ivy233 commented Apr 30, 2026

/forcemerge

@deepin-bot
Copy link
Copy Markdown

deepin-bot Bot commented Apr 30, 2026

This pr force merged! (status: blocked)

@deepin-bot deepin-bot Bot merged commit 683fa0c into linuxdeepin:master Apr 30, 2026
9 of 12 checks passed
@Ivy233 Ivy233 deleted the feat/event-logger-integration branch April 30, 2026 05:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants